;; supercollider/control-spec.scm - (c) rohan drape, 2004-2005

;; An interface to the math/warp.scm procedures.

(define-structure control-spec (minima maxima name warp))

(defineV (make-control-spec minima maxima type)
  (let ((name (if (symbol? type) type 'unknown))
	(warp (if (procedure? type) type ((symbol->warp type) minima maxima))))
    (make-control-spec* minima maxima name warp)))

(define (control-spec-range s)
  (- (control-spec-maxima s) (control-spec-minima s)))

(define (control-spec-ratio s)
  (/ (control-spec-maxima s) (control-spec-minima s)))

(define (control-spec-map s value)
  ((control-spec-warp s) 'map (number-clip value 0.0 1.0)))

(define (control-spec-unmap s value)
  (number-clip ((control-spec-warp s) 'unmap value) 0.0 1.0))

(define (control-spec->vector s)
  (vector (control-spec-minima s) 
	  (control-spec-maxima s)
	  (control-spec-name s)))

(define (symbol->control-spec s)
  (case s
    ((unipolar) (make-control-spec 0 1 'linear))
    ((bipolar pan) (make-control-spec -1 1 'linear))
    ((freq frequency) (make-control-spec 20 20000 'exponential))
    ((phase) (make-control-spec 0 two-pi 'linear))
    (else (error "symbol->control-spec: unknown control-spec" s))))

;; Aliases

(define make-spec make-control-spec)
(define spec-map control-spec-map)
(define spec-unmap control-spec-unmap)
(define symbol->spec symbol->control-spec)

;; Conversion

(define-generic as-control-spec)
(define-method (as-control-spec (s <control-spec>)) s)
(define-method (as-control-spec (s <Symbol>))       (symbol->control-spec s))
